package com.aurora.app.util.weixin;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Date;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONObject;

import com.aurora.app.entity.WeixinAppToken;
import com.aurora.base.util.QiniuUtil;
import com.aurora.base.util.StringConvertDate;



/***
 * 微信媒体上传下载类
 * 
 * 
 * @since 2014-12-17
 * @author 林佳新
 * 
 */

public class WeixinMediaUtil {
	private static final Log logger = LogFactory.getLog(WeixinMediaUtil.class);

	/* 下载媒体接口 */
	private static final String downloadMedia = "http://file.api.weixin.qq.com/cgi-bin/media/get?access_token=ACCESS_TOKEN&media_id=MEDIA_ID";

	/* 上传媒体接口 */
	private static final String uploadMediaUrl = "http://file.api.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE";

	/**
	 * 下载媒体
	 * 
	 * @param MediaId
	 *            媒体id
	 * @param ctxpath
	 * @return
	 * @throws Exception
	 */
	public static String download(String MediaId, String apptoken,
			String ctxpath) throws Exception {

		try {
			String token = apptoken;
			if (StringUtils.isBlank(token)) {
				logger.error("还未设置appid");
			}
			String requestUrl = downloadMedia.replace("ACCESS_TOKEN", token)
					.replace("MEDIA_ID", MediaId);

			URL url = new URL(requestUrl);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setDoInput(true);
			conn.setRequestMethod("GET");
			String suffix = "jpeg";
			String rootPath = ctxpath;
			// 获取文件名
			String savePath = "upload" + "/" + "media" + "/" + StringConvertDate.DateToStr(new Date(),"yyyy-MM-dd") +"/"+ MediaId + "."
					+ suffix;
			// 将mediaId作为文件名
			String filePath = rootPath + savePath;

			if (!new File(rootPath + "upload" + "/" + "media"+ "/" + StringConvertDate.DateToStr(new Date(),"yyyy-MM-dd")).exists()) {
				new File(rootPath + "upload" + "/" + "media"+ "/" + StringConvertDate.DateToStr(new Date(),"yyyy-MM-dd")).mkdirs(); // 检查文件夹是否存在，如不存在创建
			}

			BufferedInputStream bis = new BufferedInputStream(
					conn.getInputStream());
			FileOutputStream fos = new FileOutputStream(new File(filePath));
			byte[] buf = new byte[8096];
			int size = 0;
			while ((size = bis.read(buf)) != -1)
				fos.write(buf, 0, size);
			fos.close();
			bis.close();
			conn.disconnect();
			logger.info("下载媒体文件成功，filePath=" + filePath);
			if (suffix.equals("amr") || suffix.equals("speex")) {
				long length = getAmrDuration(new File(filePath));
				return ctxpath + "/" + savePath + "," + length;
			}
			
			String qiniuPath =   "ThingImg/" + MediaId
					+ System.currentTimeMillis() + "." + suffix;
			//如果失败，有6次尝试机会重新上传
			int count = 5;
			boolean res = true;
			while(count>=0){
				res = QiniuUtil.upload(QiniuUtil.bucket, qiniuPath,
						new File(filePath));
				if(!res){
					count--;
				}else{
					break;
				}
			}
			
			System.out.println(res);
			System.out.println( QiniuUtil.qiniuDomain + qiniuPath);
			return QiniuUtil.qiniuDomain + qiniuPath;
		} catch (Exception e) {
			logger.error("下载微信媒体文件失败！", e);
			throw e;
		}

	}

	/**
	 * 计算语音的时间长度
	 * 
	 * @param file
	 * @return
	 * @throws IOException
	 */
	public static long getAmrDuration(File file) throws IOException {
		long duration = -1;
		int[] packedSize = {12, 13, 15, 17, 19, 20, 26, 31, 5, 0, 0, 0, 0, 0,
				0, 0};
		RandomAccessFile randomAccessFile = null;
		try {
			randomAccessFile = new RandomAccessFile(file, "rw");
			long length = file.length();// 文件的长度
			int pos = 6;// 设置初始位置
			int frameCount = 0;// 初始帧数
			int packedPos = -1;
			byte[] datas = new byte[1];// 初始数据值
			while (pos <= length) {
				randomAccessFile.seek(pos);
				if (randomAccessFile.read(datas, 0, 1) != 1) {
					duration = length > 0 ? ((length - 6) / 650) : 0;
					break;
				}
				packedPos = (datas[0] >> 3) & 0x0F;
				pos += packedSize[packedPos] + 1;
				frameCount++;
			}
			duration += frameCount * 20;// 帧数*20
		} finally {
			if (randomAccessFile != null) {
				randomAccessFile.close();
			}
		}
		return duration;
	}

	/**
	 * 上传媒体到微信服务器
	 * 
	 * @param accessToken
	 * @param type
	 *            文件类型
	 * @param filePath
	 *            文件路径
	 * @throws Exception
	 */
	public static String uploadMedia(String type, String filePath,
			WeixinAppToken apptoken) throws Exception {
		// 拼装请求地址

		String token = apptoken.getAccessToken();
		if (token.equals("false")) {
			logger.error("还未设置appid");
		}

		String url = uploadMediaUrl.replace("ACCESS_TOKEN", token).replace(
				"TYPE", type);
		String result = null;
		File file = new File(filePath);
		if (!file.exists() || !file.isFile()) {
			throw new IOException("文件不存在");
		}
		/**
		 * 第一部分
		 */
		URL urlObj = new URL(url);
		HttpURLConnection con = (HttpURLConnection) urlObj.openConnection();
		con.setRequestMethod("POST"); // 以Post方式提交表单，默认get方式
		con.setDoInput(true);
		con.setDoOutput(true);
		con.setUseCaches(false); // post方式不能使用缓存
		// 设置请求头信息
		con.setRequestProperty("Connection", "Keep-Alive");
		con.setRequestProperty("Charset", "UTF-8");
		// 设置边界
		String BOUNDARY = "----------" + System.currentTimeMillis();
		con.setRequestProperty("Content-Type", "multipart/form-data; boundary="
				+ BOUNDARY);
		// 请求正文信息
		// 第一部分：
		StringBuilder sb = new StringBuilder();
		sb.append("--"); // 必须多两道线
		sb.append(BOUNDARY);
		sb.append("\r\n");
		sb.append("Content-Disposition: form-data;name=\"file\";filename=\""
				+ file.getName() + "\"\r\n");
		sb.append("Content-Type:application/octet-stream\r\n\r\n");
		byte[] head = sb.toString().getBytes("utf-8");
		// 获得输出流
		OutputStream out = new DataOutputStream(con.getOutputStream());
		// 输出表头
		out.write(head);
		// 文件正文部分
		// 把文件已流文件的方式 推入到url中
		DataInputStream in = new DataInputStream(new FileInputStream(file));
		int bytes = 0;
		byte[] bufferOut = new byte[1024];
		while ((bytes = in.read(bufferOut)) != -1) {
			out.write(bufferOut, 0, bytes);
		}
		in.close();
		// 结尾部分
		byte[] foot = ("\r\n--" + BOUNDARY + "--\r\n").getBytes("utf-8");// 定义最后数据分隔线
		out.write(foot);
		out.flush();
		out.close();
		StringBuffer buffer = new StringBuffer();
		BufferedReader reader = null;
		try {
			// 定义BufferedReader输入流来读取URL的响应
			reader = new BufferedReader(new InputStreamReader(
					con.getInputStream()));
			String line = null;
			while ((line = reader.readLine()) != null) {
				// System.out.println(line);
				buffer.append(line);
			}
			if (result == null) {
				result = buffer.toString();
			}
		} catch (IOException e) {
			System.out.println("发送POST请求出现异常！" + e);
			e.printStackTrace();
			return null;
		} finally {
			if (reader != null) {
				reader.close();
			}
		}
		JSONObject jsonObj = new JSONObject(result);
		logger.info("上传媒体文件到微信返回json=" + jsonObj);
		String mediaid = null;
		try {
			mediaid = jsonObj.getString("media_id");
		} catch (Exception e) {
			logger.error("上传媒体文件到微信失败！");
			return null;
		}
		return mediaid;

	}
}
